/*
 * SoftwareSAR - 1.0
 */
package br.com.cpqd.ssar.geradormalha;

import br.com.cpqd.ssar.geradormalha.gui.InterfaceRenderizacaoMalha;
import br.com.cpqd.ssar.mediador.RequisicaoServicos;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import javax.swing.filechooser.FileFilter;

/**
 * Classe que Implementa um Importador de Malhas FDTD 3D
 * @author Rafael Buck
 * @version 1.0
 */
public class ImportadorMalhaFDTD implements InterfaceRenderizacaoMalha {

    private int nx;         // numero de elementos em x
    private int ny;         // numero de elementos em y
    private int nz;         // numero de elementos em z
    private float dx;       // delta x
    private float dy;       // delta y
    private float dz;       // delta z
    /**
     * Coordenadas da Cena
     */
    private float xMin;
    private float xMax;
    private float yMin;
    private float yMax;
    private float zMin;
    private float zMax;
    /**
     * Malha 3D onde cada elemento representa um material
     */
    private int[][][] malha;

    public boolean importarMalha(RequisicaoServicos requisicaoServicos, String caminho) {

        String caminhoArquivoConfig = caminho.substring(0, caminho.length() - 5);
        caminhoArquivoConfig = caminhoArquivoConfig.concat(".config");

        try {

            /**
             * Abre Arquivo de Configuração
             */
            FileInputStream inputStream = new FileInputStream(caminhoArquivoConfig);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            String str = null;
            StringTokenizer st = null;

            // Dimensões
            str = reader.readLine();
            st = new StringTokenizer(str);
            this.nx = Integer.valueOf(st.nextToken());
            this.ny = Integer.valueOf(st.nextToken());
            this.nz = Integer.valueOf(st.nextToken());

            // Deltas
            str = reader.readLine();
            st = new StringTokenizer(str);
            this.dx = Float.valueOf(st.nextToken());
            this.dy = Float.valueOf(st.nextToken());
            this.dz = Float.valueOf(st.nextToken());

            // Unidade Dimensional
            str = reader.readLine();
            st = new StringTokenizer(str);
            requisicaoServicos.setUnidadeDimensional(st.nextToken());

            this.xMin = 0;
            this.yMin = 0;
            this.zMin = 0;

            this.xMax = nx * dx;
            this.yMax = ny * dy;
            this.zMax = nz * dz;

            reader.close();
            inputStream.close();

            /**
             * Abre Arquivo de Malha
             */
            inputStream = new FileInputStream(caminho);
            reader = new BufferedReader(new InputStreamReader(inputStream));
//            FileReader fileReader = new FileReader(caminho);
//            reader = new BufferedReader(fileReader);

            malha = new int[nx][ny][nz];

            for (int i = 0; i < nx; i++) {
                for (int j = 0; j < ny; j++) {
                    for (int k = 0; k < nz; k++) {
                        str = reader.readLine();
                        if (str != null) {
                            st = new StringTokenizer(str);
                            st.nextToken();
                            st.nextToken();
                            st.nextToken();
                            int material = Integer.valueOf(st.nextToken());
                            if (requisicaoServicos.obterMaterial(material) != null) {
                                malha[i][j][k] = material;
                            } else {
                                malha[i][j][k] = 1;
                            }
                        }
                    }
                }
            }
            reader.close();
            inputStream.close();

//            fileReader.close();
//            inputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    public boolean importarMalhaFormatoCompacto(RequisicaoServicos requisicaoServicos, String caminho) {

        String caminhoArquivoConfig = caminho.substring(0, caminho.length() - 4);
        caminhoArquivoConfig = caminhoArquivoConfig.concat(".config");

        try {

            /**
             * Abre Arquivo de Configuração
             */
            FileInputStream inputStream = new FileInputStream(caminhoArquivoConfig);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            String str = null;
            StringTokenizer st = null;

            // Dimensões
            str = reader.readLine();
            st = new StringTokenizer(str);
            this.nx = Integer.valueOf(st.nextToken());
            this.ny = Integer.valueOf(st.nextToken());
            this.nz = Integer.valueOf(st.nextToken());

            // Deltas
            str = reader.readLine();
            st = new StringTokenizer(str);
            this.dx = Float.valueOf(st.nextToken());
            this.dy = Float.valueOf(st.nextToken());
            this.dz = Float.valueOf(st.nextToken());

            // Unidade Dimensional
            str = reader.readLine();
            st = new StringTokenizer(str);
            requisicaoServicos.setUnidadeDimensional(st.nextToken());

            this.xMin = 0;
            this.yMin = 0;
            this.zMin = 0;

            this.xMax = nx * dx;
            this.yMax = ny * dy;
            this.zMax = nz * dz;

            reader.close();
            inputStream.close();

            /**
             * Abre Arquivo de Malha
             */
            inputStream = new FileInputStream(caminho);
            reader = new BufferedReader(new InputStreamReader(inputStream));
//            FileReader fileReader = new FileReader(caminho);
//            reader = new BufferedReader(fileReader);

            malha = new int[nx][ny][nz];

            for (int i = 0; i < nx; i++) {
                for (int j = 0; j < ny; j++) {
                    for (int k = 0; k < nz; k++) {
                        str = reader.readLine();
                        if (str != null) {
                            int material = Integer.valueOf(str);
                            if (requisicaoServicos.obterMaterial(material) != null) {
                                malha[i][j][k] = material;
                            } else {
                                System.out.println("erro");
                                malha[i][j][k] = 1;
                            }
                        }
                    }
                }
            }
            reader.close();
            inputStream.close();

//            fileReader.close();
//            inputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }
    
    /**
     * Retorna o filtro do Arquivo de Malha.
     * @return FileFilter
     */
    public FileFilter obterFiltroMalha() {

        FileFilter filtro = null;
        // cria o filtro associado ao tipo de arquivo STL
        filtro = new FileFilter() {

            public boolean accept(File f) {
                String fileName = f.getName().toLowerCase();
                return (fileName.endsWith(".isar") || f.isDirectory());
            }

            public String getDescription() {
                return "Malha FDTD (*.isar)";
            }
        };
        return filtro;
    }
    
    /**
     * Retorna o filtro do Arquivo de Malha.
     * @return FileFilter
     */
    public FileFilter obterFiltroMalhaFormatoCompacto() {

        FileFilter filtro = null;
        // cria o filtro associado ao tipo de arquivo STL
        filtro = new FileFilter() {

            public boolean accept(File f) {
                String fileName = f.getName().toLowerCase();
                return (fileName.endsWith(".dat") || f.isDirectory());
            }

            public String getDescription() {
                return "Malha FDTD Compacto (*.dat)";
            }
        };
        return filtro;
    }

    public int obterMaterialCubo(int i, int j, int k) {
        return malha[i][j][k];
    }

    public float getDx() {
        return dx;
    }

    public float getDy() {
        return dy;
    }

    public float getDz() {
        return dz;
    }

    public int getNx() {
        return nx;
    }

    public int getNy() {
        return ny;
    }

    public int getNz() {
        return nz;
    }

    public float getXMax() {
        return xMax;
    }

    public float getXMin() {
        return xMin;
    }

    public float getYMax() {
        return yMax;
    }

    public float getYMin() {
        return yMin;
    }

    public float getZMax() {
        return zMax;
    }

    public float getZMin() {
        return zMin;
    }
}
